using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Raxxla.DayBreak.Core
{
    /// <summary>
    /// UniqueObject  abstract class
    /// </summary>
    public abstract class UniqueObject
    {
        private static int _uniqueKeyCounter;

        protected int _uniqueKey;


        /// <summary>
        /// Returns an unique 32 int value
        /// </summary>
        public int UniqueKey
        {
            get
            {
                if (this._uniqueKey == 0)
                    CalculateKey();

                return this._uniqueKey;
            }
        }

        private void CalculateKey()
        {
            int nextValue;
            bool equals;

            do
            {
                int curCounter = UniqueObject._uniqueKeyCounter;
                nextValue = (curCounter == 0x7fffffff) ? 1 : (curCounter + 0x11);

                // Compares two 32-bit signed integers for equality and, if they are equal,
                // replaces one of the values.
                // 
                // Parameters:
                // comparand: 
                //    The value that is compared to the value at location1. 
                // location1: 
                //    The destination, whose value is compared with comparand and possibly
                //    replaced. 
                // value: 
                //    The value that replaces the destination value if the comparison results
                //    in equality. 
                // 
                // Returns:
                // The original value in location1.
                equals = Interlocked.CompareExchange(ref UniqueObject._uniqueKeyCounter, nextValue, curCounter) == curCounter;
            }
            while (!equals);

            this._uniqueKey = nextValue;
        }

    }
}
